/**
 * 认证模块 - 处理用户认证、密码加密和 JWT 令牌管理
 * 使用 jose 库进行 JWT 操作，bcryptjs 进行密码加密
 */

import { SignJWT, jwtVerify } from 'jose';
import bcrypt from 'bcryptjs';

// JWT 密钥配置，优先使用环境变量，否则使用默认值
const JWT_SECRET = process.env.JWT_SECRET || 'your-super-secret-jwt-key-change-this-in-production';
const secret = new TextEncoder().encode(JWT_SECRET);

// JWT 令牌载荷接口
export interface TokenPayload {
  userId: string;  // 用户 ID
  email: string;   // 用户邮箱
  role: string;    // 用户角色
}

/**
 * 密码加密函数
 * @param password 原始密码
 * @returns 加密后的密码哈希值
 */
export async function hashPassword(password: string): Promise<string> {
  return bcrypt.hash(password, 12);  // 使用 12 轮加密，平衡安全性和性能
}

/**
 * 密码验证函数
 * @param password 原始密码
 * @param hashedPassword 已加密的密码哈希值
 * @returns 密码是否匹配
 */
export async function verifyPassword(password: string, hashedPassword: string): Promise<boolean> {
  return bcrypt.compare(password, hashedPassword);
}

/**
 * 生成 JWT 令牌
 * @param payload 令牌载荷数据
 * @returns JWT 令牌字符串
 */
export async function generateToken(payload: TokenPayload): Promise<string> {
  const token = await new SignJWT(payload)
    .setProtectedHeader({ alg: 'HS256' })  // 使用 HMAC SHA-256 算法
    .setExpirationTime('7d')               // 设置 7 天过期时间
    .setIssuedAt()                         // 设置签发时间
    .sign(secret);                         // 使用密钥签名
  
  return token;
}

/**
 * 验证 JWT 令牌
 * @param token JWT 令牌字符串
 * @returns 解析后的令牌载荷，验证失败返回 null
 */
export async function verifyToken(token: string): Promise<TokenPayload | null> {
  try {
    const { payload } = await jwtVerify(token, secret);
    
    // 返回解析后的载荷数据
    return {
      userId: payload.userId as string,
      email: payload.email as string,
      role: payload.role as string
    };
  } catch (error) {
    // 令牌无效或过期时返回 null
    return null;
  }
}
